home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / toaplan2.c < prev    next >
C/C++ Source or Header  |  2000-04-23  |  43KB  |  1,242 lines

  1. /***************************************************************************
  2.  
  3.   Functions to emulate the video hardware of some Toaplan games
  4.  
  5.  
  6.  To Do / Unknowns
  7.     -  Hack is needed to reset sound CPU and sound chip when machine
  8.         is 'tilted'in Pipi & Bibis. Otherwise sound CPU interferes
  9.         with the main CPU test of shared RAM. You get a 'Sub CPU RAM Error'
  10.     -  What do Scroll registers 0Eh and 0Fh really do ????
  11.     -  Snow Bros 2 sets bit 6 of the sprite X info word during weather
  12.         world map, and bits 4, 5 and 6 of the sprite X info word during
  13.         the Rabbit boss screen - reasons are unknown.
  14.     -  Fourth set of scroll registers have been used for Sprite scroll
  15.         though it may not be correct. For most parts this looks right
  16.         except for Snow Bros 2 when in the rabbit boss screen (all sprites
  17.         jump when big green nasty (which is the foreground layer) comes
  18.         in from the left)
  19.     -  Teki Paki tests video RAM from address 0 past SpriteRAM to $37ff.
  20.         It doesnt seem to use that memory above SpriteRAM for anything though.
  21.     -  Teki Paki sprites seem to be three frames ahead of the tile layers.
  22.         Since this driver double buffers the sprites, Teki Paki is still
  23.         suffering sprite lag (Does it need an extra buffer - quite strange)
  24.     -  Batsugun, relationship between the two video controllers (priority
  25.         wise) is wrong and unknown.
  26.  
  27.  Video RAM address layout:
  28.  
  29.     Bank          data size of video layer
  30.     -----------------------------------------
  31.     $0000-07FF      800h words for background layer
  32.     $0800-0FFF      800h words for foreground layer
  33.     $1000-17FF      800h words for top (text) layer
  34.     $1800-1BFF      400h words for sprites (100 possible sprites)
  35.  
  36.  
  37.  
  38.  Tile RAM format (each tile takes up 32 bits)
  39.  
  40.   0         1         2         3
  41.   ---- ---- ---- ---- xxxx xxxx xxxx xxxx = Tile number (0 - FFFFh)
  42.   ---- ---- -xxx xxxx ---- ---- ---- ---- = Color (0 - 7Fh)
  43.   ---- ---- ?--- ---- ---- ---- ---- ---- = unknown / unused
  44.   ---- xxxx ---- ---- ---- ---- ---- ---- = Priority (0 - Fh)
  45.   ???? ---- ---- ---- ---- ---- ---- ---- = unknown / unused / possible flips
  46.  
  47.  
  48.  
  49. Sprites are of varying sizes between 8x8 and 128x128 and any size
  50. inbetween, in multiples of 8 either way.
  51.  
  52. Here we draw the first 8x8 part of the sprite, then by using the sprite
  53. dimensions, we draw the rest of the 8x8 parts to produce the complete
  54. sprite.
  55.  
  56. There seems to be sprite buffering - double buffering actually.
  57.  
  58.  Sprite RAM format (data for each sprite takes up 4 words)
  59.  
  60.   0
  61.   ---- ----  ---- --xx = top 2 bits of Sprite number
  62.   ---- ----  xxxx xx-- = Color (0 - 3Fh)
  63.   ---- xxxx  ---- ---- = Priority (0 - Fh)
  64.   ---x ----  ---- ---- = Flip X
  65.   --x- ----  ---- ---- = Flip Y
  66.   -?-- ----  ---- ---- = unknown / unused
  67.   x--- ----  ---- ---- = Show sprite ?
  68.  
  69.   1
  70.   xxxx xxxx  xxxx xxxx = Sprite number (top two bits in word 0)
  71.  
  72.   2
  73.   ---- ----  ---- xxxx = Sprite X size (add 1, then multiply by 8)
  74.   ---- ----  -??? ---- = unknown - used in Snow Bros. 2
  75.   xxxx xxxx  x--- ---- = X position
  76.  
  77.   3
  78.   ---- ----  ---- xxxx = Sprite Y size (add 1, then multiply by 8)
  79.   ---- ----  -??? ---- = unknown / unused
  80.   xxxx xxxx  x--- ---- = Y position
  81.  
  82.  
  83. Scroll Registers (hex) :
  84.  
  85.     00        Background scroll X (X flip off)
  86.     01        Background scroll Y (Y flip off)
  87.     02        Foreground scroll X (X flip off)
  88.     03        Foreground scroll Y (Y flip off)
  89.     04        Top (text) scroll X (X flip off)
  90.     05        Top (text) scroll Y (Y flip off)
  91.     06        Sprites    scroll X (X flip off) ???
  92.     07        Sprites    scroll Y (Y flip off) ???
  93.     0E        ???? Initialise Video controller at startup ????
  94.     0F        Scroll update complete ??? (Not used in Ghox and V-Five)
  95.  
  96.     80        Background scroll X (X flip on)
  97.     81        Background scroll Y (Y flip on)
  98.     82        Foreground scroll X (X flip on)
  99.     83        Foreground scroll Y (Y flip on)
  100.     84        Top (text) scroll X (X flip on)
  101.     85        Top (text) scroll Y (Y flip on)
  102.     86        Sprites    scroll X (X flip on) ???
  103.     87        Sprites    scroll Y (Y flip on) ???
  104.     8F        Same as 0Fh except flip bit is active
  105.  
  106.  
  107. Scroll Register 0E writes (Video controller inits ?) from different games:
  108.  
  109. Teki-Paki         | Ghox                | Knuckle Bash       | Tatsujin 2          |
  110. 0003, 0002, 4000 | ????, ????, ???? | 0202, 0203, 4200 | 0003, 0002, 4000 |
  111.  
  112. Dogyuun             | Batsugun            |
  113. 0202, 0203, 4200 | 0202, 0203, 4200 |
  114. 1202, 1203, 5200 | 1202, 1203, 5200 | <--- Second video controller ???
  115.  
  116. Pipi & Bibis     | Fix Eight        | V-Five           | Snow Bros. 2      |
  117. 0003, 0002, 4000 | 0202, 0203, 4200 | 0202, 0203, 4200 | 0202, 0203, 4200 |
  118.  
  119. ***************************************************************************/
  120.  
  121. #include "driver.h"
  122. #include "tilemap.h"
  123.  
  124. #define TOAPLAN2_DEBUG 0
  125.  
  126.  
  127. #define TOAPLAN2_BG_VRAM_SIZE    0x1000    /* Background RAM size (in bytes) */
  128. #define TOAPLAN2_FG_VRAM_SIZE    0x1000    /* Foreground RAM size (in bytes) */
  129. #define TOAPLAN2_TOP_VRAM_SIZE    0x1000    /* Top Layer  RAM size (in bytes) */
  130. #define TOAPLAN2_SPRITERAM_SIZE    0x0800    /* Sprite      RAM size (in bytes) */
  131.  
  132. #define TOAPLAN2_SPRITE_FLIPX 0x1000    /* Sprite flip flags (for screen flip) */
  133. #define TOAPLAN2_SPRITE_FLIPY 0x2000
  134.  
  135. #define CPU_2_NONE        0x00
  136. #define CPU_2_Z80        0x5a
  137. #define CPU_2_HD647180    0xa5
  138. #define CPU_2_Zx80        0xff
  139.  
  140.  
  141. static unsigned char *bgvideoram[2];
  142. static unsigned char *fgvideoram[2];
  143. static unsigned char *topvideoram[2];
  144. static unsigned char *spriteram_now[2];     /* Sprites to draw this frame */
  145. static unsigned char *spriteram_next[2]; /* Sprites to draw next frame */
  146. static unsigned char *spriteram_new[2];     /* Sprites to add to next frame */
  147. static int toaplan2_unk_vram;             /* Video RAM tested but not used (for Teki Paki)*/
  148.  
  149. static int toaplan2_scroll_reg[2];
  150. static int toaplan2_voffs[2];
  151. static int bg_offs[2];
  152. static int fg_offs[2];
  153. static int top_offs[2];
  154. static int sprite_offs[2];
  155. static int bg_scrollx[2];
  156. static int bg_scrolly[2];
  157. static int fg_scrollx[2];
  158. static int fg_scrolly[2];
  159. static int top_scrollx[2];
  160. static int top_scrolly[2];
  161. static int sprite_scrollx[2];
  162. static int sprite_scrolly[2];
  163.  
  164. #if TOAPLAN2_DEBUG
  165. static int display_bg[2]  = { 1, 1 };
  166. static int display_fg[2]  = { 1, 1 };
  167. static int display_top[2] = { 1, 1 };
  168. static int displog = 0;
  169. #endif
  170. static int display_sp[2] = { 1, 1 };
  171.  
  172. static int sprite_priority[2][16];
  173. static int bg_flip[2] = { 0, 0 };
  174. static int fg_flip[2] = { 0, 0 };
  175. static int top_flip[2] = { 0, 0 };
  176. static int sprite_flip[2] = { 0, 0 };
  177.  
  178. extern int toaplan2_sub_cpu;
  179.  
  180. static struct tilemap *top_tilemap[2], *fg_tilemap[2], *bg_tilemap[2];
  181.  
  182.  
  183. /***************************************************************************
  184.  
  185.   Callbacks for the TileMap code
  186.  
  187. ***************************************************************************/
  188.  
  189. static void get_top0_tile_info(int tile_index)
  190. {
  191.     int color, tile_number, attrib;
  192.     UINT16 *source = (UINT16 *)(topvideoram[0]);
  193.  
  194.     attrib = source[2*tile_index];
  195.     tile_number = source[2*tile_index+1];
  196.     color = attrib & 0x7f;
  197.     SET_TILE_INFO(0,tile_number,color)
  198.     tile_info.priority = (attrib & 0x0f00) >> 8;
  199. }
  200.  
  201. static void get_fg0_tile_info(int tile_index)
  202. {
  203.     int color, tile_number, attrib;
  204.     UINT16 *source = (UINT16 *)(fgvideoram[0]);
  205.  
  206.     attrib = source[2*tile_index];
  207.     tile_number = source[2*tile_index+1];
  208.     color = attrib & 0x7f;
  209.     SET_TILE_INFO(0,tile_number,color)
  210.     tile_info.priority = (attrib & 0x0f00) >> 8;
  211. }
  212.  
  213. static void get_bg0_tile_info(int tile_index)
  214. {
  215.     int color, tile_number, attrib;
  216.     UINT16 *source = (UINT16 *)(bgvideoram[0]);
  217.  
  218.     attrib = source[2*tile_index];
  219.     tile_number = source[2*tile_index+1];
  220.     color = attrib & 0x7f;
  221.     SET_TILE_INFO(0,tile_number,color)
  222.     tile_info.priority = (attrib & 0x0f00) >> 8;
  223. }
  224.  
  225.  
  226. static void get_top1_tile_info(int tile_index)
  227. {
  228.     int color, tile_number, attrib;
  229.     UINT16 *source = (UINT16 *)(topvideoram[1]);
  230.  
  231.     attrib = source[2*tile_index];
  232.     tile_number = source[2*tile_index+1];
  233.     color = attrib & 0x7f;
  234.     SET_TILE_INFO(2,tile_number,color)
  235.     tile_info.priority = (attrib & 0x0f00) >> 8;
  236. }
  237.  
  238. static void get_fg1_tile_info(int tile_index)
  239. {
  240.     int color, tile_number, attrib;
  241.     UINT16 *source = (UINT16 *)(fgvideoram[1]);
  242.  
  243.     attrib = source[2*tile_index];
  244.     tile_number = source[2*tile_index+1];
  245.     color = attrib & 0x7f;
  246.     SET_TILE_INFO(2,tile_number,color)
  247.     tile_info.priority = (attrib & 0x0f00) >> 8;
  248. }
  249.  
  250. static void get_bg1_tile_info(int tile_index)
  251. {
  252.     int color, tile_number, attrib;
  253.     UINT16 *source = (UINT16 *)(bgvideoram[1]);
  254.  
  255.     attrib = source[2*tile_index];
  256.     tile_number = source[2*tile_index+1];
  257.     color = attrib & 0x7f;
  258.     SET_TILE_INFO(2,tile_number,color)
  259.     tile_info.priority = (attrib & 0x0f00) >> 8;
  260. }
  261.  
  262.  
  263.  
  264. /***************************************************************************
  265.  
  266.   Start the video hardware emulation.
  267.  
  268. ***************************************************************************/
  269. static void toaplan2_vh_stop(int controller)
  270. {
  271.     free(     bgvideoram[controller] );
  272.     free(     fgvideoram[controller] );
  273.     free(    topvideoram[controller] );
  274.     free(  spriteram_now[controller] );
  275.     free( spriteram_next[controller] );
  276.     free(  spriteram_new[controller] );
  277. }
  278. void toaplan2_0_vh_stop(void)
  279. {
  280.     toaplan2_vh_stop(0);
  281. }
  282. void toaplan2_1_vh_stop(void)
  283. {
  284.     toaplan2_vh_stop(1);
  285.     toaplan2_vh_stop(0);
  286. }
  287.  
  288.  
  289. static int create_tilemaps_0(void)
  290. {
  291.     top_tilemap[0] = tilemap_create(get_top0_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
  292.     fg_tilemap[0] = tilemap_create(get_fg0_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
  293.     bg_tilemap[0] = tilemap_create(get_bg0_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
  294.  
  295.     if (!top_tilemap[0] || !fg_tilemap[0] || !bg_tilemap[0])
  296.         return 1;
  297.  
  298.     top_tilemap[0]->transparent_pen = 0;
  299.     fg_tilemap[0]->transparent_pen = 0;
  300.     bg_tilemap[0]->transparent_pen = 0;
  301.  
  302.     return 0;
  303. }
  304. static int create_tilemaps_1(void)
  305. {
  306.     top_tilemap[1] = tilemap_create(get_top1_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
  307.     fg_tilemap[1] = tilemap_create(get_fg1_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
  308.     bg_tilemap[1] = tilemap_create(get_bg1_tile_info,tilemap_scan_rows,TILEMAP_TRANSPARENT,16,16,32,32);
  309.  
  310.     if (!top_tilemap[1] || !fg_tilemap[1] || !bg_tilemap[1])
  311.         return 1;
  312.  
  313.     top_tilemap[1]->transparent_pen = 0;
  314.     fg_tilemap[1]->transparent_pen = 0;
  315.     bg_tilemap[1]->transparent_pen = 0;
  316.  
  317.     return 0;
  318. }
  319.  
  320. static int toaplan2_vh_start(int controller)
  321. {
  322.     static int error_level = 0;
  323.     if ((spriteram_new[controller] = malloc(TOAPLAN2_SPRITERAM_SIZE)) == 0)
  324.     {
  325.         return 1;
  326.     }
  327.     memset(spriteram_new[controller],0,TOAPLAN2_SPRITERAM_SIZE);
  328.  
  329.     if ((spriteram_next[controller] = malloc(TOAPLAN2_SPRITERAM_SIZE)) == 0)
  330.     {
  331.         free( spriteram_new[controller] );
  332.         return 1;
  333.     }
  334.     memset(spriteram_next[controller],0,TOAPLAN2_SPRITERAM_SIZE);
  335.  
  336.     if ((spriteram_now[controller] = malloc(TOAPLAN2_SPRITERAM_SIZE)) == 0)
  337.     {
  338.         free( spriteram_next[controller] );
  339.         free(  spriteram_new[controller] );
  340.         return 1;
  341.     }
  342.     memset(spriteram_now[controller],0,TOAPLAN2_SPRITERAM_SIZE);
  343.  
  344.     if ((topvideoram[controller] = malloc(TOAPLAN2_TOP_VRAM_SIZE)) == 0)
  345.     {
  346.         free(  spriteram_now[controller] );
  347.         free( spriteram_next[controller] );
  348.         free(  spriteram_new[controller] );
  349.         return 1;
  350.     }
  351.     memset(topvideoram[controller],0,TOAPLAN2_TOP_VRAM_SIZE);
  352.  
  353.     if ((fgvideoram[controller] = malloc(TOAPLAN2_FG_VRAM_SIZE)) == 0)
  354.     {
  355.         free(    topvideoram[controller] );
  356.         free(  spriteram_now[controller] );
  357.         free( spriteram_next[controller] );
  358.         free(  spriteram_new[controller] );
  359.         return 1;
  360.     }
  361.     memset(fgvideoram[controller],0,TOAPLAN2_FG_VRAM_SIZE);
  362.  
  363.     if ((bgvideoram[controller] = malloc(TOAPLAN2_BG_VRAM_SIZE)) == 0)
  364.     {
  365.         free(     fgvideoram[controller] );
  366.         free(    topvideoram[controller] );
  367.         free(  spriteram_now[controller] );
  368.         free( spriteram_next[controller] );
  369.         free(  spriteram_new[controller] );
  370.         return 1;
  371.     }
  372.     memset(bgvideoram[controller],0,TOAPLAN2_BG_VRAM_SIZE);
  373.  
  374.     if (controller == 0)
  375.     {
  376.         error_level |= create_tilemaps_0();
  377.     }
  378.     if (controller == 1)
  379.     {
  380.         error_level |= create_tilemaps_1();
  381.     }
  382.     return error_level;
  383. }
  384. int toaplan2_0_vh_start(void)
  385. {
  386.     return toaplan2_vh_start(0);
  387. }
  388. int toaplan2_1_vh_start(void)
  389. {
  390.     int error_level = 0;
  391.     error_level |= toaplan2_vh_start(0);
  392.     error_level |= toaplan2_vh_start(1);
  393.     return error_level;
  394. }
  395.  
  396.  
  397.  
  398. /***************************************************************************
  399.  
  400.   Video I/O port hardware.
  401.  
  402. ***************************************************************************/
  403.  
  404. void toaplan2_voffs_w(int offset, int data, int controller)
  405. {
  406.     toaplan2_voffs[controller] = data;
  407.  
  408.     /* Layers are seperated by ranges in the offset */
  409.     switch (data & 0xfc00)
  410.     {
  411.         case 0x0400:
  412.         case 0x0000:    bg_offs[controller] = (data & 0x7ff) * 2; break;
  413.         case 0x0c00:
  414.         case 0x0800:    fg_offs[controller] = (data & 0x7ff) * 2; break;
  415.         case 0x1400:
  416.         case 0x1000:    top_offs[controller] = (data & 0x7ff) * 2; break;
  417.         case 0x1800:    sprite_offs[controller] = (data & 0x3ff) * 2; break;
  418.         default:        logerror("Hmmm, unknown video controller %01x layer being selected (%08x)\n",controller,data);
  419.                         data &= 0x1800;
  420.                         if ((data & 0x1800) == 0x0000)
  421.                             bg_offs[controller] = (data & 0x7ff) * 2;
  422.                         if ((data & 0x1800) == 0x0800)
  423.                             fg_offs[controller] = (data & 0x7ff) * 2;
  424.                         if ((data & 0x1800) == 0x1000)
  425.                             top_offs[controller] = (data & 0x7ff) * 2;
  426.                         if ((data & 0x1800) == 0x1800)
  427.                             sprite_offs[controller] = (data & 0x3ff) * 2;
  428.                         break;
  429.     }
  430. }
  431. WRITE_HANDLER( toaplan2_0_voffs_w )
  432. {
  433.     toaplan2_voffs_w(offset, data, 0);
  434. }
  435. WRITE_HANDLER( toaplan2_1_voffs_w )
  436. {
  437.     toaplan2_voffs_w(offset, data, 1);
  438. }
  439.  
  440. int toaplan2_videoram_r(int offset, int controller)
  441. {
  442.     static int video_data = 0;
  443.     int videoram_offset;
  444.  
  445.     switch (toaplan2_voffs[controller] & 0xfc00)
  446.     {
  447.         case 0x0400:
  448.         case 0x0000:
  449.                 videoram_offset = bg_offs[controller] & (TOAPLAN2_BG_VRAM_SIZE-1);
  450.                 video_data = READ_WORD (&bgvideoram[controller][videoram_offset]);
  451.                 bg_offs[controller] += 2;
  452.                 if (bg_offs[controller] > TOAPLAN2_BG_VRAM_SIZE)
  453.                 {
  454.                     logerror("Reading %04x from out of range BG Layer address (%08x)  Video controller %01x  !!!\n",video_data,bg_offs[controller],controller);
  455.                 }
  456.                 break;
  457.         case 0x0c00:
  458.         case 0x0800:
  459.                 videoram_offset = fg_offs[controller] & (TOAPLAN2_FG_VRAM_SIZE-1);
  460.                 video_data = READ_WORD (&fgvideoram[controller][videoram_offset]);
  461.                 fg_offs[controller] += 2;
  462.                 if (fg_offs[controller] > TOAPLAN2_FG_VRAM_SIZE)
  463.                 {
  464.                     logerror("Reading %04x from out of range FG Layer address (%08x)  Video controller %01x  !!!\n",video_data,fg_offs[controller],controller);
  465.                 }
  466.                 break;
  467.         case 0x1400:
  468.         case 0x1000:
  469.                 videoram_offset = top_offs[controller] & (TOAPLAN2_TOP_VRAM_SIZE-1);
  470.                 video_data = READ_WORD (&topvideoram[controller][videoram_offset]);
  471.                 top_offs[controller] += 2;
  472.                 if (top_offs[controller] > TOAPLAN2_TOP_VRAM_SIZE)
  473.                 {
  474.                     logerror("Reading %04x from out of range TOP Layer address (%08x)  Video controller %01x  !!!\n",video_data,top_offs[controller],controller);
  475.                 }
  476.                 break;
  477.         case 0x1800:
  478.                 videoram_offset = sprite_offs[controller] & (TOAPLAN2_SPRITERAM_SIZE-1);
  479.                 video_data = READ_WORD (&spriteram_new[controller][videoram_offset]);
  480.                 sprite_offs[controller] += 2;
  481.                 if (sprite_offs[controller] > TOAPLAN2_SPRITERAM_SIZE)
  482.                 {
  483.                     logerror("Reading %04x from out of range Sprite address (%08x)  Video controller %01x  !!!\n",video_data,sprite_offs[controller],controller);
  484.                 }
  485.                 break;
  486.         default:
  487.                 video_data = toaplan2_unk_vram;
  488.                 logerror("Hmmm, reading %04x from unknown video layer (%08x)  Video controller %01x  !!!\n",video_data,toaplan2_voffs[controller],controller);
  489.                 break;
  490.     }
  491.     return video_data;
  492. }
  493. READ_HANDLER( toaplan2_0_videoram_r )
  494. {
  495.     return toaplan2_videoram_r(offset, 0);
  496. }
  497. READ_HANDLER( toaplan2_1_videoram_r )
  498. {
  499.     return toaplan2_videoram_r(offset, 1);
  500. }
  501.  
  502. void toaplan2_videoram_w(int offset, int data, int controller)
  503. {
  504.     int oldword = 0;
  505.     int videoram_offset;
  506.     int dirty_cell;
  507.  
  508.     switch (toaplan2_voffs[controller] & 0xfc00)
  509.     {
  510.         case 0x0400:
  511.         case 0x0000:
  512.                 videoram_offset = bg_offs[controller] & (TOAPLAN2_BG_VRAM_SIZE-1);
  513.                 oldword = READ_WORD (&bgvideoram[controller][videoram_offset]);
  514.                 if (data != oldword)
  515.                 {
  516.                     WRITE_WORD (&bgvideoram[controller][videoram_offset],data);
  517.                     dirty_cell = (bg_offs[controller] & (TOAPLAN2_BG_VRAM_SIZE-3))/2;
  518.                     tilemap_mark_tile_dirty(bg_tilemap[controller],dirty_cell/2);
  519.                 }
  520.                 bg_offs[controller] += 2;
  521.                 if (bg_offs[controller] > TOAPLAN2_BG_VRAM_SIZE)
  522.                 {
  523.                     logerror("Writing %04x to out of range BG Layer address (%08x)  Video controller %01x  !!!\n",data,bg_offs[controller],controller);
  524.                 }
  525.                 break;
  526.         case 0x0c00:
  527.         case 0x0800:
  528.                 videoram_offset = fg_offs[controller] & (TOAPLAN2_FG_VRAM_SIZE-1);
  529.                 oldword = READ_WORD (&fgvideoram[controller][videoram_offset]);
  530.                 if (data != oldword)
  531.                 {
  532.                     WRITE_WORD (&fgvideoram[controller][videoram_offset],data);
  533.                     dirty_cell = (fg_offs[controller] & (TOAPLAN2_FG_VRAM_SIZE-3))/2;
  534.                     tilemap_mark_tile_dirty(fg_tilemap[controller],dirty_cell/2);
  535.                 }
  536.                 fg_offs[controller] += 2;
  537.                 if (fg_offs[controller] > TOAPLAN2_FG_VRAM_SIZE)
  538.                 {
  539.                     logerror("Writing %04x to out of range FG Layer address (%08x)  Video controller %01x  !!!\n",data,fg_offs[controller],controller);
  540.                 }
  541.                 break;
  542.         case 0x1400:
  543.         case 0x1000:
  544.                 videoram_offset = top_offs[controller] & (TOAPLAN2_TOP_VRAM_SIZE-1);
  545.                 oldword = READ_WORD (&topvideoram[controller][videoram_offset]);
  546.                 if (data != oldword)
  547.                 {
  548.                     WRITE_WORD (&topvideoram[controller][videoram_offset],data);
  549.                     dirty_cell = (top_offs[controller] & (TOAPLAN2_TOP_VRAM_SIZE-3))/2;
  550.                     tilemap_mark_tile_dirty(top_tilemap[controller],dirty_cell/2);
  551.                 }
  552.                 top_offs[controller] += 2;
  553.                 if (top_offs[controller] > TOAPLAN2_TOP_VRAM_SIZE)
  554.                 {
  555.                     logerror("Writing %04x to out of range TOP Layer address (%08x)  Video controller %01x  !!!\n",data,top_offs[controller],controller);
  556.                 }
  557.                 break;
  558.         case 0x1800:
  559.                 videoram_offset = sprite_offs[controller] & (TOAPLAN2_SPRITERAM_SIZE-1);
  560.                 WRITE_WORD (&spriteram_new[controller][videoram_offset],data);
  561.                 sprite_offs[controller] += 2;
  562.                 if (sprite_offs[controller] > TOAPLAN2_SPRITERAM_SIZE)
  563.                 {
  564.                     logerror("Writing %04x to out of range Sprite address (%08x)  Video controller %01x  !!!\n",data,sprite_offs[controller],controller);
  565.                 }
  566.                 break;
  567.         default:
  568.                 toaplan2_unk_vram = data;
  569.                 logerror("Hmmm, writing %04x to unknown video layer (%08x)  Video controller %01x  \n",toaplan2_unk_vram,toaplan2_voffs[controller],controller);
  570.                 break;
  571.     }
  572. }
  573. WRITE_HANDLER( toaplan2_0_videoram_w )
  574. {
  575.     toaplan2_videoram_w(offset, data, 0);
  576. }
  577. WRITE_HANDLER( toaplan2_1_videoram_w )
  578. {
  579.     toaplan2_videoram_w(offset, data, 1);
  580. }
  581.  
  582.  
  583. void toaplan2_scroll_reg_select_w(int offset, int data, int controller)
  584. {
  585.     toaplan2_scroll_reg[controller] = data;
  586.     if (toaplan2_scroll_reg[controller] & 0xffffff70)
  587.     {
  588.         logerror("Hmmm, unknown video control register selected (%08x)  Video controller %01x  \n",toaplan2_scroll_reg[controller],controller);
  589.     }
  590. }
  591. WRITE_HANDLER( toaplan2_0_scroll_reg_select_w )
  592. {
  593.     toaplan2_scroll_reg_select_w(offset, data, 0);
  594. }
  595. WRITE_HANDLER( toaplan2_1_scroll_reg_select_w )
  596. {
  597.     toaplan2_scroll_reg_select_w(offset, data, 1);
  598. }
  599.  
  600.  
  601. void toaplan2_scroll_reg_data_w(int offset, int data, int controller)
  602. {
  603.     /************************************************************************/
  604.     /***** X and Y layer flips can be set independantly, so emulate it ******/
  605.     /************************************************************************/
  606.  
  607. //    int vid_controllers = 1;
  608.  
  609.     switch(toaplan2_scroll_reg[controller])
  610.     {
  611.         case 0x00:    bg_scrollx[controller] = data - 0x1d6;            /* 1D6h */
  612.                     bg_flip[controller] &= (~TILEMAP_FLIPX);
  613.                     tilemap_set_flip(bg_tilemap[controller],bg_flip[controller]);
  614.                     tilemap_set_scrollx(bg_tilemap[controller],0,bg_scrollx[controller]);
  615.                     break;
  616.         case 0x01:    bg_scrolly[controller] = data - 0x1ef;            /* 1EFh */
  617.                     bg_flip[controller] &= (~TILEMAP_FLIPY);
  618.                     tilemap_set_flip(bg_tilemap[controller],bg_flip[controller]);
  619.                     tilemap_set_scrolly(bg_tilemap[controller],0,bg_scrolly[controller]);
  620.                     break;
  621.         case 0x02:    fg_scrollx[controller] = data - 0x1d8;            /* 1D0h */
  622.                     fg_flip[controller] &= (~TILEMAP_FLIPX);
  623.                     tilemap_set_flip(fg_tilemap[controller],fg_flip[controller]);
  624.                     tilemap_set_scrollx(fg_tilemap[controller],0,fg_scrollx[controller]);
  625.                     break;
  626.         case 0x03:  fg_scrolly[controller] = data - 0x1ef;            /* 1EFh */
  627.                     fg_flip[controller] &= (~TILEMAP_FLIPY);
  628.                     tilemap_set_flip(fg_tilemap[controller],fg_flip[controller]);
  629.                     tilemap_set_scrolly(fg_tilemap[controller],0,fg_scrolly[controller]);
  630.                     break;
  631.         case 0x04:    top_scrollx[controller] = data - 0x1da;            /* 1DAh */
  632.                     top_flip[controller] &= (~TILEMAP_FLIPX);
  633.                     tilemap_set_flip(top_tilemap[controller],top_flip[controller]);
  634.                     tilemap_set_scrollx(top_tilemap[controller],0,top_scrollx[controller]);
  635.                     break;
  636.         case 0x05:    top_scrolly[controller] = data - 0x1ef;            /* 1EFh */
  637.                     top_flip[controller] &= (~TILEMAP_FLIPY);
  638.                     tilemap_set_flip(top_tilemap[controller],top_flip[controller]);
  639.                     tilemap_set_scrolly(top_tilemap[controller],0,top_scrolly[controller]);
  640.                     break;
  641.         case 0x06:    sprite_scrollx[controller] = data - 0x1cc;        /* 1D4h */
  642.                     if (sprite_scrollx[controller] & 0x80000000) sprite_scrollx[controller] |= 0xfffffe00;
  643.                     else sprite_scrollx[controller] &= 0x1ff;
  644.                     sprite_flip[controller] &= (~TOAPLAN2_SPRITE_FLIPX);
  645.                     break;
  646.         case 0x07:    sprite_scrolly[controller] = data - 0x1ef;        /* 1F7h */
  647.                     if (sprite_scrolly[controller] & 0x80000000) sprite_scrolly[controller] |= 0xfffffe00;
  648.                     else sprite_scrolly[controller] &= 0x1ff;
  649.                     sprite_flip[controller] &= (~TOAPLAN2_SPRITE_FLIPY);
  650.                     break;
  651.         case 0x0f:    break;
  652.         case 0x80:  bg_scrollx[controller] = data - 0x229;            /* 169h */
  653.                     bg_flip[controller] |= TILEMAP_FLIPX;
  654.                     tilemap_set_flip(bg_tilemap[controller],bg_flip[controller]);
  655.                     tilemap_set_scrollx(bg_tilemap[controller],0,bg_scrollx[controller]);
  656.                     break;
  657.         case 0x81:    bg_scrolly[controller] = data - 0x210;            /* 100h */
  658.                     bg_flip[controller] |= TILEMAP_FLIPY;
  659.                     tilemap_set_flip(bg_tilemap[controller],bg_flip[controller]);
  660.                     tilemap_set_scrolly(bg_tilemap[controller],0,bg_scrolly[controller]);
  661.                     break;
  662.         case 0x82:    fg_scrollx[controller] = data - 0x227;            /* 15Fh */
  663.                     fg_flip[controller] |= TILEMAP_FLIPX;
  664.                     tilemap_set_flip(fg_tilemap[controller],fg_flip[controller]);
  665.                     tilemap_set_scrollx(fg_tilemap[controller],0,fg_scrollx[controller]);
  666.                     break;
  667.         case 0x83:    fg_scrolly[controller] = data - 0x210;            /* 100h */
  668.                     fg_flip[controller] |= TILEMAP_FLIPY;
  669.                     tilemap_set_flip(fg_tilemap[controller],fg_flip[controller]);
  670.                     tilemap_set_scrolly(fg_tilemap[controller],0,fg_scrolly[controller]);
  671.                     break;
  672.         case 0x84:    top_scrollx[controller] = data - 0x225;            /* 165h */
  673.                     top_flip[controller] |= TILEMAP_FLIPX;
  674.                     tilemap_set_flip(top_tilemap[controller],top_flip[controller]);
  675.                     tilemap_set_scrollx(top_tilemap[controller],0,top_scrollx[controller]);
  676.                     break;
  677.         case 0x85:    top_scrolly[controller] = data - 0x210;            /* 100h */
  678.                     top_flip[controller] |= TILEMAP_FLIPY;
  679.                     tilemap_set_flip(top_tilemap[controller],top_flip[controller]);
  680.                     tilemap_set_scrolly(top_tilemap[controller],0,top_scrolly[controller]);
  681.                     break;
  682.         case 0x86:    sprite_scrollx[controller] = data - 0x17b;        /* 17Bh */
  683.                     if (sprite_scrollx[controller] & 0x80000000) sprite_scrollx[controller] |= 0xfffffe00;
  684.                     else sprite_scrollx[controller] &= 0x1ff;
  685.                     sprite_flip[controller] |= TOAPLAN2_SPRITE_FLIPX;
  686.                     break;
  687.         case 0x87:    sprite_scrolly[controller] = data - 0x108;        /* 108h */
  688.                     if (sprite_scrolly[controller] & 0x80000000) sprite_scrolly[controller] |= 0xfffffe00;
  689.                     else sprite_scrolly[controller] &= 0x1ff;
  690.                     sprite_flip[controller] |= TOAPLAN2_SPRITE_FLIPY;
  691.                     break;
  692.         case 0x8f:    break;
  693.  
  694.         case 0x0e:    /******* Initialise video controller register ? *******/
  695.                     if ((toaplan2_sub_cpu == CPU_2_Z80) && (data == 3))
  696.                     {
  697.                         /* HACK! When tilted, sound CPU needs to be reset. */
  698.                         cpu_set_reset_line(1,PULSE_LINE);
  699.                         YM3812_sh_reset();
  700.                     }
  701.         default:    logerror("Hmmm, writing %08x to unknown video control register (%08x)  Video controller %01x  !!!\n",data ,toaplan2_scroll_reg[controller],controller);
  702.                     break;
  703.     }
  704.  
  705. #if TOAPLAN2_DEBUG
  706.  
  707.     if (spriteram_now[1] && spriteram_next[1] && spriteram_new[1]
  708.         && top_tilemap[1] && fg_tilemap[1] && bg_tilemap[1])
  709.     {
  710.         vid_controllers = 2;
  711.     }
  712.  
  713.     if ( keyboard_pressed(KEYCODE_L) )
  714.     {
  715.         while (keyboard_pressed(KEYCODE_L)) ;
  716.         display_sp[0] += 1;
  717.         display_sp[0] &= 1;
  718.     }
  719.     if ( keyboard_pressed(KEYCODE_K) )
  720.     {
  721.         while (keyboard_pressed(KEYCODE_K)) ;
  722.         display_top[0] += 1;
  723.         display_top[0] &= 1;
  724.         tilemap_set_enable(top_tilemap[0], display_top[0]);
  725.     }
  726.     if ( keyboard_pressed(KEYCODE_J) )
  727.     {
  728.         while (keyboard_pressed(KEYCODE_J)) ;
  729.         display_fg[0] += 1;
  730.         display_fg[0] &= 1;
  731.         tilemap_set_enable(fg_tilemap[0], display_fg[0]);
  732.     }
  733.     if ( keyboard_pressed(KEYCODE_H) )
  734.     {
  735.         while (keyboard_pressed(KEYCODE_H)) ;
  736.         display_bg[0] += 1;
  737.         display_bg[0] &= 1;
  738.         tilemap_set_enable(bg_tilemap[0], display_bg[0]);
  739.     }
  740.     if (vid_controllers == 2)
  741.     {
  742.         if ( keyboard_pressed(KEYCODE_O) )
  743.         {
  744.             while (keyboard_pressed(KEYCODE_O)) ;
  745.             display_sp[1] += 1;
  746.             display_sp[1] &= 1;
  747.         }
  748.         if ( keyboard_pressed(KEYCODE_I) )
  749.         {
  750.             while (keyboard_pressed(KEYCODE_I)) ;
  751.             display_top[1] += 1;
  752.             display_top[1] &= 1;
  753.             tilemap_set_enable(top_tilemap[1], display_top[1]);
  754.         }
  755.         if ( keyboard_pressed(KEYCODE_U) )
  756.         {
  757.             while (keyboard_pressed(KEYCODE_U)) ;
  758.             display_fg[1] += 1;
  759.             display_fg[1] &= 1;
  760.             tilemap_set_enable(fg_tilemap[1], display_fg[1]);
  761.         }
  762.         if ( keyboard_pressed(KEYCODE_Y) )
  763.         {
  764.             while (keyboard_pressed(KEYCODE_Y)) ;
  765.             display_bg[1] += 1;
  766.             display_bg[1] &= 1;
  767.             tilemap_set_enable(bg_tilemap[1], display_bg[1]);
  768.         }
  769.     }
  770. #endif
  771. }
  772. WRITE_HANDLER( toaplan2_0_scroll_reg_data_w )
  773. {
  774.     toaplan2_scroll_reg_data_w(offset, data, 0);
  775. }
  776. WRITE_HANDLER( toaplan2_1_scroll_reg_data_w )
  777. {
  778.     toaplan2_scroll_reg_data_w(offset, data, 1);
  779. }
  780.  
  781.  
  782. #if TOAPLAN2_DEBUG
  783. void toaplan2_log_vram(void)
  784. {
  785.     int sprite_voffs, tile_voffs, vid_controllers = 1;
  786.  
  787.     if (spriteram_now[1] && spriteram_next[1] && spriteram_new[1]
  788.         && top_tilemap[1] && fg_tilemap[1] && bg_tilemap[1])
  789.     {
  790.         vid_controllers = 2;
  791.     }
  792.  
  793.     if ( keyboard_pressed(KEYCODE_M) )
  794.     {
  795.         UINT16 *source_now0  = (UINT16 *)(spriteram_now[0]);
  796.         UINT16 *source_next0 = (UINT16 *)(spriteram_next[0]);
  797.         UINT16 *source_new0  = (UINT16 *)(spriteram_new[0]);
  798.         UINT16 *source_now1;
  799.         UINT16 *source_next1;
  800.         UINT16 *source_new1;
  801.  
  802.         int schar[3],sattr[3],sxpos[3],sypos[3];
  803.  
  804.         if (vid_controllers == 2)
  805.         {
  806.             source_now1  = (UINT16 *)(spriteram_now[1]);
  807.             source_next1 = (UINT16 *)(spriteram_next[1]);
  808.             source_new1  = (UINT16 *)(spriteram_new[1]);
  809.         }
  810.  
  811.         while (keyboard_pressed(KEYCODE_M)) ;
  812.         logerror("Scrolls   BG-X  BG-Y   FG-X  FG-Y   TOP-X  TOP-Y   Sprite-X  Sprite-Y\n");
  813.         logerror("---0-->   %04x  %04x   %04x  %04x    %04x  %04x       %04x    %04x\n", bg_scrollx[0],bg_scrolly[0],fg_scrollx[0],fg_scrolly[0],top_scrollx[0],top_scrolly[0],sprite_scrollx[0], sprite_scrolly[0]);
  814.         if (vid_controllers == 2)
  815.         {
  816.             logerror("---1-->   %04x  %04x   %04x  %04x    %04x  %04x       %04x    %04x\n", bg_scrollx[1],bg_scrolly[1],fg_scrollx[1],fg_scrolly[1],top_scrollx[1],top_scrolly[1],sprite_scrollx[1], sprite_scrolly[1]);
  817.         }
  818.         for ( sprite_voffs = 0; sprite_voffs < (TOAPLAN2_SPRITERAM_SIZE/2); sprite_voffs+=4 )
  819.         {
  820.             sattr[0] = source_now0[sprite_voffs];
  821.             schar[0] = source_now0[sprite_voffs + 1];
  822.             sxpos[0] = source_now0[sprite_voffs + 2];
  823.             sypos[0] = source_now0[sprite_voffs + 3];
  824.             sattr[1] = source_next0[sprite_voffs];
  825.             schar[1] = source_next0[sprite_voffs + 1];
  826.             sxpos[1] = source_next0[sprite_voffs + 2];
  827.             sypos[1] = source_next0[sprite_voffs + 3];
  828.             sattr[2] = source_new0[sprite_voffs];
  829.             schar[2] = source_new0[sprite_voffs + 1];
  830.             sxpos[2] = source_new0[sprite_voffs + 2];
  831.             sypos[2] = source_new0[sprite_voffs + 3];
  832.             logerror("SPoffs     Sprt Attr Xpos Ypos     Sprt Attr Xpos Ypos     Sprt Attr Xpos Ypos\n");
  833.             logerror("0:%03x now:%04x %04x %04x %04x nxt:%04x %04x %04x %04x new:%04x %04x %04x %04x\n",sprite_voffs,
  834.                                                  schar[0], sattr[0],sxpos[0], sypos[0],
  835.                                                  schar[1], sattr[1],sxpos[1], sypos[1],
  836.                                                  schar[2], sattr[2],sxpos[2], sypos[2]);
  837.             if (vid_controllers == 2)
  838.             {
  839.                 sattr[0] = source_now1[sprite_voffs];
  840.                 schar[0] = source_now1[sprite_voffs + 1];
  841.                 sxpos[0] = source_now1[sprite_voffs + 2];
  842.                 sypos[0] = source_now1[sprite_voffs + 3];
  843.                 sattr[1] = source_next1[sprite_voffs];
  844.                 schar[1] = source_next1[sprite_voffs + 1];
  845.                 sxpos[1] = source_next1[sprite_voffs + 2];
  846.                 sypos[1] = source_next1[sprite_voffs + 3];
  847.                 sattr[2] = source_new1[sprite_voffs];
  848.                 schar[2] = source_new1[sprite_voffs + 1];
  849.                 sxpos[2] = source_new1[sprite_voffs + 2];
  850.                 sypos[2] = source_new1[sprite_voffs + 3];
  851.                 logerror("1:%03x now:%04x %04x %04x %04x nxt:%04x %04x %04x %04x new:%04x %04x %04x %04x\n",sprite_voffs,
  852.                                                  schar[0], sattr[0],sxpos[0], sypos[0],
  853.                                                  schar[1], sattr[1],sxpos[1], sypos[1],
  854.                                                  schar[2], sattr[2],sxpos[2], sypos[2]);
  855.             }
  856.         }
  857.     }
  858.     if ( keyboard_pressed(KEYCODE_N) )
  859.     {
  860.         int tchar[2], tattr[2];
  861.         while (keyboard_pressed(KEYCODE_N)) ;
  862.         logerror("Scrolls   BG-X  BG-Y   FG-X  FG-Y   TOP-X  TOP-Y   Sprite-X  Sprite-Y\n");
  863.         logerror("---0-->   %04x  %04x   %04x  %04x    %04x  %04x       %04x    %04x\n", bg_scrollx[0],bg_scrolly[0],fg_scrollx[0],fg_scrolly[0],top_scrollx[0],top_scrolly[0],sprite_scrollx[0], sprite_scrolly[0]);
  864.         if (vid_controllers == 2)
  865.         {
  866.             logerror("---1-->   %04x  %04x   %04x  %04x    %04x  %04x       %04x    %04x\n", bg_scrollx[1],bg_scrolly[1],fg_scrollx[1],fg_scrolly[1],top_scrollx[1],top_scrolly[1],sprite_scrollx[1], sprite_scrolly[1]);
  867.         }
  868.         for ( tile_voffs = 0; tile_voffs < TOAPLAN2_TOP_VRAM_SIZE; tile_voffs+=4 )
  869.         {
  870.             tchar[0] = READ_WORD (&topvideoram[0][tile_voffs + 2]);
  871.             tattr[0] = READ_WORD (&topvideoram[0][tile_voffs]);
  872.             if (vid_controllers == 2)
  873.             {
  874.                 tchar[1] = READ_WORD (&topvideoram[1][tile_voffs + 2]);
  875.                 tattr[1] = READ_WORD (&topvideoram[1][tile_voffs]);
  876.                 logerror("TXoffs:%04x   Tile0:%04x  Attr0:%04x    Tile1:%04x  Attr1:%04x\n", tile_voffs/2, tchar[0], tattr[0], tchar[1], tattr[1]);
  877.             }
  878.             else
  879.             {
  880.                 logerror("TXoffs:%04x   Tile0:%04x  Attr0:%04x\n", tile_voffs/2, tchar[0], tattr[0]);
  881.             }
  882.         }
  883.     }
  884.     if ( keyboard_pressed(KEYCODE_B) )
  885.     {
  886.         int tchar[2], tattr[2];
  887.         while (keyboard_pressed(KEYCODE_B)) ;
  888.         logerror("Scrolls   BG-X  BG-Y   FG-X  FG-Y   TOP-X  TOP-Y   Sprite-X  Sprite-Y\n");
  889.         logerror("---0-->   %04x  %04x   %04x  %04x    %04x  %04x       %04x    %04x\n", bg_scrollx[0],bg_scrolly[0],fg_scrollx[0],fg_scrolly[0],top_scrollx[0],top_scrolly[0],sprite_scrollx[0], sprite_scrolly[0]);
  890.         if (vid_controllers == 2)
  891.         {
  892.             logerror("---1-->   %04x  %04x   %04x  %04x    %04x  %04x       %04x    %04x\n", bg_scrollx[1],bg_scrolly[1],fg_scrollx[1],fg_scrolly[1],top_scrollx[1],top_scrolly[1],sprite_scrollx[1], sprite_scrolly[1]);
  893.         }
  894.         for ( tile_voffs = 0; tile_voffs < TOAPLAN2_FG_VRAM_SIZE; tile_voffs+=4 )
  895.         {
  896.             tchar[0] = READ_WORD (&fgvideoram[0][tile_voffs + 2]);
  897.             tattr[0] = READ_WORD (&fgvideoram[0][tile_voffs]);
  898.         if (vid_controllers == 2)
  899.             {
  900.                 tchar[1] = READ_WORD (&fgvideoram[1][tile_voffs + 2]);
  901.                 tattr[1] = READ_WORD (&fgvideoram[1][tile_voffs]);
  902.                 logerror("FGoffs:%04x   Tile0:%04x  Attr0:%04x    Tile1:%04x  Attr1:%04x\n", tile_voffs/2, tchar[0], tattr[0], tchar[1], tattr[1]);
  903.             }
  904.             else
  905.             {
  906.                 logerror("FGoffs:%04x   Tile0:%04x  Attr0:%04x\n", tile_voffs/2, tchar[0], tattr[0]);
  907.             }
  908.         }
  909.     }
  910.     if ( keyboard_pressed(KEYCODE_V) )
  911.     {
  912.         int tchar[2], tattr[2];
  913.         while (keyboard_pressed(KEYCODE_V)) ;
  914.         logerror("Scrolls   BG-X  BG-Y   FG-X  FG-Y   TOP-X  TOP-Y   Sprite-X  Sprite-Y\n");
  915.         logerror("---0-->   %04x  %04x   %04x  %04x    %04x  %04x       %04x    %04x\n", bg_scrollx[0],bg_scrolly[0],fg_scrollx[0],fg_scrolly[0],top_scrollx[0],top_scrolly[0],sprite_scrollx[0], sprite_scrolly[0]);
  916.         if (vid_controllers == 2)
  917.         {
  918.             logerror("---1-->   %04x  %04x   %04x  %04x    %04x  %04x       %04x    %04x\n", bg_scrollx[1],bg_scrolly[1],fg_scrollx[1],fg_scrolly[1],top_scrollx[1],top_scrolly[1],sprite_scrollx[1], sprite_scrolly[1]);
  919.         }
  920.         for ( tile_voffs = 0; tile_voffs < TOAPLAN2_BG_VRAM_SIZE; tile_voffs+=4 )
  921.         {
  922.             tchar[0] = READ_WORD (&bgvideoram[0][tile_voffs + 2]);
  923.             tattr[0] = READ_WORD (&bgvideoram[0][tile_voffs]);
  924.             if (vid_controllers == 2)
  925.             {
  926.                 tchar[1] = READ_WORD (&bgvideoram[1][tile_voffs + 2]);
  927.                 tattr[1] = READ_WORD (&bgvideoram[1][tile_voffs]);
  928.                 logerror("BGoffs:%04x   Tile0:%04x  Attr0:%04x    Tile1:%04x  Attr1:%04x\n", tile_voffs/2, tchar[0], tattr[0], tchar[1], tattr[1]);
  929.             }
  930.             else
  931.             {
  932.                 logerror("BGoffs:%04x   Tile0:%04x  Attr0:%04x\n", tile_voffs/2, tchar[0], tattr[0]);
  933.             }
  934.         }
  935.     }
  936.  
  937.     if ( keyboard_pressed(KEYCODE_C) )
  938.     {
  939.         while (keyboard_pressed(KEYCODE_C)) ;
  940.         logerror("Mark here\n");
  941.     }
  942.     if ( keyboard_pressed(KEYCODE_G) )
  943.     {
  944.         while (keyboard_pressed(KEYCODE_G)) ;
  945.         displog += 1;
  946.         displog &= 1;
  947.     }
  948.     if (displog)
  949.     {
  950.         logerror("Scrolls   BG-X  BG-Y   FG-X  FG-Y   TOP-X  TOP-Y   Sprite-X  Sprite-Y\n");
  951.         logerror("---0-->   %04x  %04x   %04x  %04x    %04x  %04x       %04x    %04x\n", bg_scrollx[0],bg_scrolly[0],fg_scrollx[0],fg_scrolly[0],top_scrollx[0],top_scrolly[0],sprite_scrollx[0], sprite_scrolly[0]);
  952.         if (vid_controllers == 2)
  953.         {
  954.             logerror("---1-->   %04x  %04x   %04x  %04x    %04x  %04x       %04x    %04x\n", bg_scrollx[1],bg_scrolly[1],fg_scrollx[1],fg_scrolly[1],top_scrollx[1],top_scrolly[1],sprite_scrollx[1], sprite_scrolly[1]);
  955.         }
  956.     }
  957. }
  958. #endif
  959.  
  960. /***************************************************************************
  961.     Sprite Handlers
  962. ***************************************************************************/
  963.  
  964. static void mark_sprite_colors(int controller)
  965. {
  966.     int offs, attrib, sprite, color, i, pal_base;
  967.     int sprite_sizex, sprite_sizey, temp_x, temp_y;
  968.     int colmask[64];
  969.  
  970.     UINT16 *source = (UINT16 *)(spriteram_now[controller]);
  971.  
  972.     pal_base = Machine->drv->gfxdecodeinfo[ ((controller*2)+1) ].color_codes_start;
  973.  
  974.     for(i=0; i < 64; i++) colmask[i] = 0;
  975.  
  976.     for (offs = 0; offs < (TOAPLAN2_SPRITERAM_SIZE/2); offs += 4)
  977.     {
  978.         attrib = source[offs];
  979.         sprite = source[offs + 1] | ((attrib & 3) << 16);
  980.         sprite %= Machine->gfx[ ((controller*2)+1) ]->total_elements;
  981.         if (attrib & 0x8000)
  982.         {
  983.             /* While we're here, mark all priorities used */
  984.             sprite_priority[controller][((attrib & 0x0f00) >> 8)] = display_sp[controller];
  985.  
  986.             color = (attrib >> 2) & 0x3f;
  987.             sprite_sizex = (source[offs + 2] & 0x0f) + 1;
  988.             sprite_sizey = (source[offs + 3] & 0x0f) + 1;
  989.  
  990.             for (temp_y = 0; temp_y < sprite_sizey; temp_y++)
  991.             {
  992.                 for (temp_x = 0; temp_x < sprite_sizex; temp_x++)
  993.                 {
  994.                     colmask[color] |= Machine->gfx[ ((controller*2)+1) ]->pen_usage[sprite];
  995.                     sprite++ ;
  996.                 }
  997.             }
  998.         }
  999.     }
  1000.  
  1001.     for (color = 0;color < 64;color++)
  1002.     {
  1003.         if ((color == 0) && (colmask[0] & 1))
  1004.             palette_used_colors[pal_base + 16 * color] = PALETTE_COLOR_TRANSPARENT;
  1005.         for (i = 1; i < 16; i++)
  1006.         {
  1007.             if (colmask[color] & (1 << i))
  1008.                 palette_used_colors[pal_base + 16 * color + i] = PALETTE_COLOR_USED;
  1009.         }
  1010.     }
  1011. }
  1012.  
  1013.  
  1014.  
  1015. static void draw_sprites( struct osd_bitmap *bitmap, int controller, int priority_to_display )
  1016. {
  1017.     const struct GfxElement *gfx = Machine->gfx[ ((controller*2)+1) ];
  1018.     const struct rectangle *clip = &Machine->drv->visible_area;
  1019.  
  1020.     UINT16 *source = (UINT16 *)(spriteram_now[controller]);
  1021.  
  1022.     int offs;
  1023.     for (offs = 0; offs < (TOAPLAN2_SPRITERAM_SIZE/2); offs += 4)
  1024.     {
  1025.         int attrib, sprite, color, priority, flipx, flipy, sx, sy;
  1026.         int sprite_sizex, sprite_sizey, temp_x, temp_y, sx_base, sy_base;
  1027.  
  1028.         attrib = source[offs];
  1029.         priority = (attrib & 0x0f00) >> 8;
  1030.  
  1031.         if ((priority == priority_to_display) && (attrib & 0x8000))
  1032.         {
  1033.             sprite = ((attrib & 3) << 16) | source[offs + 1] ;    /* 18 bit */
  1034.             color = (attrib >> 2) & 0x3f;
  1035.  
  1036.             /****** find out sprite size ******/
  1037.             sprite_sizex = ((source[offs + 2] & 0x0f) + 1) * 8;
  1038.             sprite_sizey = ((source[offs + 3] & 0x0f) + 1) * 8;
  1039.  
  1040.             /****** find position to display sprite ******/
  1041.             sx_base = (source[offs + 2] >> 7) - sprite_scrollx[controller];
  1042.             sy_base = (source[offs + 3] >> 7) - sprite_scrolly[controller];
  1043.  
  1044.             flipx = attrib & TOAPLAN2_SPRITE_FLIPX;
  1045.             flipy = attrib & TOAPLAN2_SPRITE_FLIPY;
  1046.  
  1047.             if (flipx)
  1048.             {
  1049.                 sx_base -= 7;
  1050.                 /****** wrap around sprite position ******/
  1051.                 if (sx_base >= 0x1c0) sx_base -= 0x200;
  1052.             }
  1053.             else
  1054.             {
  1055.                 if (sx_base >= 0x180) sx_base -= 0x200;
  1056.             }
  1057.  
  1058.             if (flipy)
  1059.             {
  1060.                 sy_base -= 7;
  1061.                 if (sy_base >= 0x1c0) sy_base -= 0x200;
  1062.             }
  1063.             else
  1064.             {
  1065.                 if (sy_base >= 0x180) sy_base -= 0x200;
  1066.             }
  1067.  
  1068.             /****** flip the sprite layer in any active X or Y flip ******/
  1069.             if (sprite_flip[controller])
  1070.             {
  1071.                 if (sprite_flip[controller] & TOAPLAN2_SPRITE_FLIPX)
  1072.                     sx_base = 320 - sx_base;
  1073.                 if (sprite_flip[controller] & TOAPLAN2_SPRITE_FLIPY)
  1074.                     sy_base = 240 - sy_base;
  1075.             }
  1076.  
  1077.             /****** cancel flip, if it and sprite layer flip are active ******/
  1078.             flipx = (flipx ^ (sprite_flip[controller] & TOAPLAN2_SPRITE_FLIPX));
  1079.             flipy = (flipy ^ (sprite_flip[controller] & TOAPLAN2_SPRITE_FLIPY));
  1080.  
  1081.             for (temp_y = 0; temp_y < sprite_sizey; temp_y += 8)
  1082.             {
  1083.                 if (flipy) sy = sy_base - temp_y;
  1084.                 else       sy = sy_base + temp_y;
  1085.                 for (temp_x = 0; temp_x < sprite_sizex; temp_x += 8)
  1086.                 {
  1087.                     if (flipx) sx = sx_base - temp_x;
  1088.                     else       sx = sx_base + temp_x;
  1089.  
  1090.                     drawgfx(bitmap,gfx,sprite,
  1091.                         color,
  1092.                         flipx,flipy,
  1093.                         sx,sy,
  1094.                         clip,TRANSPARENCY_PEN,0);
  1095.  
  1096.                     sprite++ ;
  1097.                 }
  1098.             }
  1099.         }
  1100.     }
  1101. }
  1102.  
  1103. /***************************************************************************
  1104.  
  1105.   Draw the game screen in the given osd_bitmap.
  1106.  
  1107. ***************************************************************************/
  1108.  
  1109. void toaplan2_0_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1110. {
  1111.     int priority;
  1112.  
  1113.     for (priority = 0; priority < 16; priority++)
  1114.         sprite_priority[0][priority] = 0;        /* Clear priorities used list */
  1115.  
  1116. #if TOAPLAN2_DEBUG
  1117.     toaplan2_log_vram();
  1118. #endif
  1119.  
  1120.     tilemap_update(ALL_TILEMAPS);
  1121.  
  1122.     palette_init_used_colors();
  1123.     mark_sprite_colors(0);    /* Also mark priorities used */
  1124.  
  1125.     if (palette_recalc()) tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
  1126.  
  1127.     tilemap_render(ALL_TILEMAPS);
  1128.  
  1129.     fillbitmap(bitmap,palette_transparent_pen,&Machine->drv->visible_area);
  1130.  
  1131.     for (priority = 0; priority < 16; priority++)
  1132.     {
  1133.         tilemap_draw(bitmap,bg_tilemap[0],priority);
  1134.         tilemap_draw(bitmap,fg_tilemap[0],priority);
  1135.         tilemap_draw(bitmap,top_tilemap[0],priority);
  1136.         if (sprite_priority[0][priority])
  1137.             draw_sprites(bitmap,0,priority);
  1138.     }
  1139. }
  1140. void toaplan2_1_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1141. {
  1142.     int priority;
  1143.  
  1144.     for (priority = 0; priority < 16; priority++)
  1145.     {
  1146.         sprite_priority[0][priority] = 0;        /* Clear priorities used list */
  1147.         sprite_priority[1][priority] = 0;        /* Clear priorities used list */
  1148.     }
  1149.  
  1150. #if TOAPLAN2_DEBUG
  1151.     toaplan2_log_vram();
  1152. #endif
  1153.  
  1154.     tilemap_update(ALL_TILEMAPS);
  1155.  
  1156.     palette_init_used_colors();
  1157.     mark_sprite_colors(0);    /* Also mark priorities used */
  1158.     mark_sprite_colors(1);    /* Also mark priorities used */
  1159.  
  1160.     if (palette_recalc()) tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
  1161.  
  1162.     tilemap_render(ALL_TILEMAPS);
  1163.  
  1164.     fillbitmap(bitmap,palette_transparent_pen,&Machine->drv->visible_area);
  1165.  
  1166.     for (priority = 0; priority < 16; priority++)
  1167.     {
  1168.         tilemap_draw(bitmap,bg_tilemap[1],priority);
  1169.         tilemap_draw(bitmap,fg_tilemap[1],priority);
  1170.         tilemap_draw(bitmap,top_tilemap[1],priority);
  1171.         if (sprite_priority[1][priority])
  1172.             draw_sprites(bitmap,1,priority);
  1173.     }
  1174.     for (priority = 0; priority < 16; priority++)
  1175.     {
  1176.         tilemap_draw(bitmap,bg_tilemap[0],priority);
  1177.         tilemap_draw(bitmap,fg_tilemap[0],priority);
  1178.         tilemap_draw(bitmap,top_tilemap[0],priority);
  1179.         if (sprite_priority[0][priority])
  1180.             draw_sprites(bitmap,0,priority);
  1181.     }
  1182. }
  1183. void batsugun_1_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  1184. {
  1185.     int priority;
  1186.  
  1187.     for (priority = 0; priority < 16; priority++)
  1188.     {
  1189.         sprite_priority[0][priority] = 0;        /* Clear priorities used list */
  1190.         sprite_priority[1][priority] = 0;        /* Clear priorities used list */
  1191.     }
  1192.  
  1193. #if TOAPLAN2_DEBUG
  1194.     toaplan2_log_vram();
  1195. #endif
  1196.  
  1197.     tilemap_update(ALL_TILEMAPS);
  1198.  
  1199.     palette_init_used_colors();
  1200.     mark_sprite_colors(0);    /* Also mark priorities used */
  1201.     mark_sprite_colors(1);    /* Also mark priorities used */
  1202.  
  1203.     if (palette_recalc()) tilemap_mark_all_pixels_dirty(ALL_TILEMAPS);
  1204.  
  1205.     tilemap_render(ALL_TILEMAPS);
  1206.  
  1207.     fillbitmap(bitmap,palette_transparent_pen,&Machine->drv->visible_area);
  1208.  
  1209.     for (priority = 0; priority < 16; priority++)
  1210.     {
  1211.         tilemap_draw(bitmap,bg_tilemap[1],priority);
  1212.         tilemap_draw(bitmap,bg_tilemap[0],priority);
  1213.         tilemap_draw(bitmap,fg_tilemap[1],priority);
  1214.         tilemap_draw(bitmap,top_tilemap[1],priority);
  1215.         if (sprite_priority[1][priority])
  1216.             draw_sprites(bitmap,1,priority);
  1217.     }
  1218.     for (priority = 0; priority < 16; priority++)
  1219.     {
  1220.         tilemap_draw(bitmap,fg_tilemap[0],priority);
  1221.         tilemap_draw(bitmap,top_tilemap[0],priority);
  1222.         if (sprite_priority[0][priority])
  1223.             draw_sprites(bitmap,0,priority);
  1224.     }
  1225. }
  1226.  
  1227.  
  1228. void toaplan2_0_eof_callback(void)
  1229. {
  1230.     /** Shift sprite RAM buffers  ***  Used to fix sprite lag **/
  1231.     memcpy(spriteram_now[0],spriteram_next[0],TOAPLAN2_SPRITERAM_SIZE);
  1232.     memcpy(spriteram_next[0],spriteram_new[0],TOAPLAN2_SPRITERAM_SIZE);
  1233. }
  1234. void toaplan2_1_eof_callback(void)
  1235. {
  1236.     /** Shift sprite RAM buffers  ***  Used to fix sprite lag **/
  1237.     memcpy(spriteram_now[0],spriteram_next[0],TOAPLAN2_SPRITERAM_SIZE);
  1238.     memcpy(spriteram_next[0],spriteram_new[0],TOAPLAN2_SPRITERAM_SIZE);
  1239.     memcpy(spriteram_now[1],spriteram_next[1],TOAPLAN2_SPRITERAM_SIZE);
  1240.     memcpy(spriteram_next[1],spriteram_new[1],TOAPLAN2_SPRITERAM_SIZE);
  1241. }
  1242.